﻿#include <stdlib.h>
#include "CMetalSlug.h"

#define BACKGROUND  "1thing.png"
#define MARCO		"Leg_Run1_31x20_18.png"
#define MARCO_LEG_JUMP_UP	"Leg_Jump_18_24_1.png"
#define MARCO_LEG_RUN		"Leg_Run1_31x20_18.png"
#define MARCO_LEG_STANDON	"Leg_StandOn_21x16_4_16.png"

#define GROUND_Y	600	//the ground
#define MAX_Y		260				//the max jump

#define RIGHT	0
#define LEFT	1

//constant variables to check if key is down, use for multiple key press
#define KEY_UP 0 
#define KEY_DOWN1 1
#define KEY_LEFT 2
#define KEY_RIGHT 3
#define KEY_SHOT 4
#define KEY_GRENADE 5
#define KEY_JUMP 6

CMetalSlug::CMetalSlug(HINSTANCE hInstance, LPCSTR GameName, int iMode, bool bIsWindowed, int iFPS):
CGame(hInstance, GameName, iMode, bIsWindowed, iFPS)
{	
	scale = (float)mi_ScreenWidth / 320 - 0.4f;
	m_bIsAction = false;
	m_BackGround = NULL;
	Tree = new CQuadTree(1363*(int)scale, 600);
	Screen = new CScreen( 0, 0, 1363*(int)scale, 600);
	deltaMovCame = 0;
	m_nAbCame = 0;
}

CMetalSlug::~CMetalSlug()
{
	Tree = NULL;
}

//virtual methods
void CMetalSlug::LoadResource()
{
	m_BackGround = CGame::CreateSurfaceFromFile(BACKGROUND);

	HRESULT result = D3DXCreateSprite(mp_Direct3D->GetDirectDevice(), &m_SpriteHandler);

	mp_Direct3D->GetDirectDevice()->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_BackBuffer);
	
	Marco = new CMarco(m_SpriteHandler, scale, Tree);
	Rebel = new CRebel(m_SpriteHandler, scale, Tree);
	Tree->addObj(Tree->m_qRoot, Rebel);
	Tree->addObj(Tree->m_qRoot, Marco);
	InitRebel();
	KeyDown[KEY_UP] = false;
	KeyDown[KEY_DOWN1] = false;
	KeyDown[KEY_RIGHT] = false;
	KeyDown[KEY_LEFT] = false;
	KeyDown[KEY_GRENADE] = false;
	KeyDown[KEY_JUMP] = false;
	KeyDown[KEY_SHOT] = false;
}

void CMetalSlug::ProcessInput(void)
{
	//LEFT ARROW press event
	//run to the left
	if (KEY_DOWN(DIK_LEFT))
	{
		KeyDown[KEY_LEFT] = mb_IsKeyPressed = true;

		if (Marco->IsJump())
			return;
		Marco->Run(LEFT);
	}
	//RIGHT ARROW press event
	//run to the right
	if (KEY_DOWN(DIK_RIGHT))
	{
		KeyDown[KEY_RIGHT] = mb_IsKeyPressed = true;

		if (Marco->IsJump())
			return;
		Marco->Run(RIGHT);
	}

	if (KEY_DOWN(DIK_DOWN))
	{
		KeyDown[KEY_DOWN1] = mb_IsKeyPressed = true;
		Marco->Crouch();
	}

	if (KEY_DOWN(DIK_UP))
	{
		KeyDown[KEY_UP] = mb_IsKeyPressed = true;
	}
	else if (!mb_IsKeyPressed)
	{
		DWORD now = GetTickCount();

		if (Marco->mb_IsJump)
		{
			return;
		}
		else
		{
			if ( !(Marco->mb_IsRelax)&&(now - mdw_LastKeyPress)/1000 > 5)
			{
				Marco->Relax();
				mdw_LastKeyPress = now;
			}
			else
			{
				Marco->Stand();
			}
		}
	}
}

void CMetalSlug::RenderFrame(void)
{
	Tree->updateObject(Screen->m_RCamera, mdw_DeltaTime, Screen->m_RCamera.left);
	//Marco->Update(mdw_DeltaTime);
	RECT r;
	r.left = Screen->m_RCamera.left/scale;
	r.top = 0;
	r.right = Screen->m_RCamera.right/scale;
	r.bottom = 289;

	mp_Direct3D->GetDirectDevice()->StretchRect(m_BackGround,	//from
												&r,			//which protion
												m_BackBuffer,	//to
												NULL,			//which protion
												D3DTEXF_POINT);	//filter which is decide how to stretch the source image to Destination Rect
	
	//lock the surface so that the sprite can be draw
	m_SpriteHandler->Begin(D3DXSPRITE_ALPHABLEND); 
	
	//set the sampler state that tell the device which technology will be use to render
	mp_Direct3D->GetDirectDevice()->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
	//Marco->Render();
	if(Marco->m_nAndr >= 350 && Marco->m_nAndr < 2412)
		Screen->MoveCamera(Marco->m_nAndr);

	Tree->drawObj(Screen->m_RCamera);
	for (int i = 0; i < Marco->m_varrayBullets.size(); i++)
	{
		Object* ob;
		ob = Tree->checkCollision(Tree->m_qRoot, *Marco->m_varrayBullets[i]->m_ObRect, 0);
		if(ob != NULL)
		{
			if(ob->m_nId != 3)
				Tank->tankFire();
			ob->die();
			Marco->Bullet[Marco->m_nbulletIndex]->m_nAndr = Marco->m_nAndr + 500;
		}
	}
	
	//unlock the surface for other processes to use
	m_SpriteHandler->End();
}

void CMetalSlug::InitRebel()
{
	Rebel = new CRebel(m_SpriteHandler, scale, Tree);
	Rebel->m_nAndr = 1400;
	Rebel->m_fverX = 2;
	Rebel->move();
	Tree->addObj(Tree->m_qRoot, Rebel);
	//
	Rebel = new CRebel(m_SpriteHandler, scale, Tree);
	Rebel->m_nAndr = 900;
	Rebel->talkFone();
	Tree->addObj(Tree->m_qRoot, Rebel);
	//
	Tank = new CtowerTank( m_SpriteHandler, scale, Tree);
	Tree->addObj(Tree->m_qRoot, Tank);
}

void CMetalSlug::OnKeyUp(int iKeyCode)
{
	mb_IsKeyPressed = false;

	switch (iKeyCode)
	{
	case DIK_UP:
		KeyDown[KEY_UP] = false;
		break;

	case DIK_DOWN:
		KeyDown[KEY_DOWN1] = false;
		break;

	case DIK_LEFT:
		KeyDown[KEY_LEFT] = false;
		break;

	case DIK_RIGHT:
		KeyDown[KEY_RIGHT] = false;
		break;

	case DIK_Z:
		KeyDown[KEY_SHOT] = false;
		break;

	case DIK_X:
		KeyDown[KEY_GRENADE] = false;
		break;

	case DIK_SPACE:
		KeyDown[KEY_JUMP] = false;
		break;
	}
}

void CMetalSlug::OnKeyDown(int iKeyCode)
{	
	switch (iKeyCode)
	{
		//left arrow key is down
		//
	case DIK_LEFT:
		{
			KeyDown[KEY_LEFT] =  mb_IsKeyPressed = true;		

			if (KeyDown[KEY_DOWN1])
				Marco->CrouchMove(LEFT);
			if ( Marco->IsJump() )
				Marco->setVerlocityX(-0.2f);
			break;
		}

		//right arrow key is down
		//
	case DIK_RIGHT:
		{
			KeyDown[KEY_RIGHT] =  mb_IsKeyPressed = true;

			if (KeyDown[KEY_DOWN1])
				Marco->CrouchMove(RIGHT);
			else if (Marco->IsJump())
				Marco->setVerlocityX(0.2f);
			break;
		}

		//up arrow key is down
		//
	case DIK_UP:
		{
			KeyDown[KEY_UP] =  mb_IsKeyPressed = true;
			if (KeyDown[KEY_SHOT])
				Marco->ShotUp();
			break;
		}

		//down arrow key is down
		//
	case DIK_DOWN:
		{
			KeyDown[KEY_DOWN1] =  mb_IsKeyPressed = true;	

			if ( (KeyDown[KEY_SHOT]) && (Marco->IsJump()) )
				Marco->ShotDown();

			else
				Marco->Crouch();
			break;
		}

		//shot key is down
		//
	case DIK_Z:
		{
			KeyDown[KEY_SHOT] =  mb_IsKeyPressed = true;

			if (KeyDown[KEY_DOWN1])
				Marco->CrouchShot();
			else
				Marco->Shot();

			/*if ( Marco->IsAction() && (Marco->GetBodyIndex() < 5) )
				Marco->Shot();*/

			break;
		}

		//throw grenade key is down
		//
	case DIK_X:
		{
			KeyDown[KEY_GRENADE] =  mb_IsKeyPressed = true;

			Marco->ThrowGrenade();

			break;
		}

		//jump key is down
		//
	case DIK_SPACE:
		{
			KeyDown[KEY_JUMP] =  mb_IsKeyPressed = true;

			if (KeyDown[KEY_LEFT])
				Marco->JumpFar(LEFT);
			else if (KeyDown[KEY_RIGHT])
				Marco->JumpFar(RIGHT);
			else
				Marco->JumpUp();

			break;
		}
	default:
		{
			if (mb_IsKeyPressed)
			{
				mdw_LastKeyPress = GetTickCount();
			}
		}
	}
}

